package org.meb.lotrlcg.web.core;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.meb.lotrlcg.db.model.UserSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@WebFilter("/*")
public class LogSessionFilter implements Filter {

	private static final Logger log = LoggerFactory.getLogger(LogSessionFilter.class);
	
	private static Set<String> sessionCache = new HashSet<String>();  
	
	@Inject
	private EntityManager em;

	public LogSessionFilter() {
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}

	public void destroy() {
	}

	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		//
		// HttpSession session = request.getSession(false);
		// String path = request.getContextPath() + request.getServletPath();
		//
		// boolean resource = path.contains("javax.faces.resource");
		// boolean ajax =
		// "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
		//
		// boolean redirect = false;
		// if (path.endsWith("expired.jsf")) {
		// redirect = false;
		// } else if (session == null) {
		// if (resource) {
		// // response.sendError(404, "Blah");
		// } else if (ajax) {
		// redirect = true;
		// }
		// } else {
		// log.info("----- session -----");
		// boolean validSession = (Boolean) session.getAttribute("valid");
		// log.info("new: {}, valid: {}", session.isNew(), validSession);
		// log.info("requestPath: {}", path);
		// log.info("----- session -----");
		// redirect = !validSession;
		// }
		//
		// if (redirect) {
		// // response.sendRedirect(request.getContextPath() + "/expired.jsf");
		// throw new SessionExpiredException();
		// } else {
		// chain.doFilter(servletRequest, servletResponse);
		// }
		boolean logged = tryLogSession(request);
		chain.doFilter(servletRequest, servletResponse);
		if (!logged) {
			tryLogSession(request);
		}
	}

	private synchronized boolean tryLogSession(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session != null && !session.isNew() && !sessionCache.contains(session.getId())) {
			try {
				UserSession userSession = new UserSession();
				userSession.setSessionId(session.getId());
				userSession.setStartDate(new Date(session.getCreationTime()));
				userSession.setUserAgent(request.getHeader("User-Agent"));
				String ip = request.getHeader("X-Forwarded-For");
				log.info("session id: {}", session.getId());
				log.info("path: {}", request.getContextPath() + request.getServletPath());
				if (ip == null) {
					ip = request.getRemoteAddr();
					userSession.setUserIp(ip);
				}
//				em.persist(userSession);
				sessionCache.add(session.getId());
				return true;
			} catch (Exception e) {
				return false;
			}
		} else {
			return false;
		}
	}
}
